package cn.dengta.webapp.trade.dto;

import java.math.BigDecimal;
import java.util.Date;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import cn.dengta.common.context.RequestContext;
import cn.dengta.webapp.base.entity.BaseEntity;
import cn.dengta.webapp.trade.entity.UserIntegral;
import cn.dengta.webapp.trade.entity.UserIntegralLog;
import cn.dengta.webapp.trade.model.TradeType;
import cn.dengta.webapp.trade.model.TradeTypeCore;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

@Getter
@Setter
@Accessors(chain = true)
public class IntegralTradeDTO extends TradeDTO<BigDecimal> {

	/** 关联消费者的钻石日志记录 */
	@Nullable
	protected Long userCoinLogId;

	protected TradeType coinTradeType;
	/** 推广员 */
	protected Long agentId;
	/** 邀请人 */
	protected Long inviteUserId;
	/** 重置积分【平台使用】 */
	protected Integer resetStatus;
	/** 业务标识类型 */
	protected Long liveId;
	/** 充值钻部分所得积分 */
	protected BigDecimal rechargeAmount;
	/** 活动钻或者平台赠送部分所得积分 */
	protected BigDecimal freeAmount;
	/** 钻石来源 */
	protected UserIntegralLog.CoinForm coinForm;
	/** Ai标识 */
	protected Long aiId;

	/**
	 * 如果外部已经进行对积分账户进行了 FOR UPDATE，则可以直接传入，内部将直接使用此对象。
	 * 要求必须是 fromUserId 的账户。
	 */
	protected transient UserIntegral userIntegralForUpdate;

	public void buildCoinForm(int totalAmount, int freeAmount) {
		this.coinForm = new UserIntegralLog.CoinForm(totalAmount - freeAmount, freeAmount);
	}

	public static IntegralTradeDTO of(Long userId, TradeType tradeType, Long toUserId, BigDecimal tradeAmount, @Nonnull BaseEntity assocObj, String ip, Date now, TradeType coinTradeType) {
		IntegralTradeDTO dto = of(userId, tradeType, toUserId, tradeAmount, assocObj, ip, now);
		dto.setCoinTradeType(coinTradeType);
		return dto;
	}

	public static IntegralTradeDTO of(Long userId, TradeType tradeType, Long toUserId, BigDecimal tradeAmount, @Nonnull BaseEntity assocObj, String ip, Date now) {
		IntegralTradeDTO dto = new IntegralTradeDTO();
		dto.init(userId, tradeType, toUserId, tradeAmount, assocObj);
		dto.init(ip, now);
		return dto;
	}

	public static IntegralTradeDTO of(Long userId, TradeType tradeType, Long toUserId, BigDecimal tradeAmount, BigDecimal freeAmount, @Nonnull BaseEntity assocObj, String ip, Date now) {
		IntegralTradeDTO dto = new IntegralTradeDTO();
		dto.init(userId, tradeType, toUserId, tradeAmount, assocObj);
		TradeTypeCore coreType = tradeType.getCoreType(true);
		if (coreType.isIncome() && freeAmount != null) {
			dto.setFreeAmount(freeAmount);
			dto.setRechargeAmount(tradeAmount.subtract(freeAmount));
		}
		dto.init(ip, now);
		return dto;
	}

	public static IntegralTradeDTO of(Long userId, TradeType tradeType, Long toUserId, BigDecimal tradeAmount, @Nonnull BaseEntity assocObj, RequestContext req) {
		return of(userId, tradeType, toUserId, tradeAmount, assocObj, req.clientIP(), req.now());
	}

	@Override
	public IntegralTradeDTO setRemark(@Nullable String remark) {
		super.setRemark(remark);
		return this;
	}

}
